"""
Case Type   : 资源池化-推进oldest_xmin
Case Name   : 修改ss_txnstatus_cache_size,备节点重启加入;
Create At   : 2024/4/24
Owner       : zhengxue
Description :
    1、查询ss_txnstatus_cache_size默认值,show ss_txnstatus_cache_size;
    2、修改ss_txnstatus_cache_size为262144,gs_guc set -D {cluster/dn1} -c "ss_txnstatus_cache_size=262144"，重启集群;
    3、运行tpcc业务,主节点写业务，备节点读业务;
    4、备节点1踢出;
    5、查询集群状态;
    6、备节点重启加入;
    7、查询集群状态;
    8、修改ss_txnstatus_cache_size为默认值,gs_guc set -D {cluster/dn1} -c "ss_txnstatus_cache_size=131072"，重启集群;
Expect      :
    1、显示默认值ss_txnstatus_cache_size
    2、参数修改成功;
    3、tpcc运行正常;
    4、备节点1踢出成功;
    5、集群状态degraded;
    6、备节点重启加入成功;
    7、集群状态正常;
    6、恢复默认值成功;
History     :
"""

import os
import time
import unittest
from yat.test import Node
from yat.test import macro
from testcase.utils.Logger import Logger
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.ComThread import ComThread

Primary_SH = CommonSH('PrimaryDbUser')
Primary_ROOTSH = CommonSH('PrimaryRoot')

class SharedStorage(unittest.TestCase):
    def setUp(self):
        self.logger = Logger()
        self.com = Common()
        self.constant = Constant()
        self.primaryRoot = Node('PrimaryRoot')
        self.logger.info("===Opengauss_Function_Guc_ForwardOldestXmin_Case0002开始执行===")
        status =  Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.logger.info(status)

        self.assertTrue("Degraded" in status or "Normal" in status)

        self.txnstatus_cache_size_default = 131072
        self.txnstatus_cache_size_set = 262144
        self.txnstatus_cache_size = 'ss_txnstatus_cache_size'

    def test_forward_oldest_xmin(self):
        step1 = '======step1:查询ss_txnstatus_cache_size,默认值为131072;expect:查询成功======'
        self.logger.info(step1)
        show_ss_txnstatus_cache_size = Primary_SH.execut_db_sql('''show ss_txnstatus_cache_size;''')
        self.logger.info(show_ss_txnstatus_cache_size)
        if '131072' in show_ss_txnstatus_cache_size:
            self.assertEqual("131072", show_ss_txnstatus_cache_size.split("\n")[-2].strip())
        else:
            result1 = Primary_SH.execute_gsguc(
            'set', self.constant.GSGUC_SUCCESS_MSG,
            f'{self.txnstatus_cache_size}={self.txnstatus_cache_size_default}')
            restart_res = Primary_SH.restart_db_cluster()
            show_txnstatus_cache_size = self.com.show_param(self.txnstatus_cache_size)
            self.assertEquals(show_txnstatus_cache_size, '131072', 'txnstatus_cache_size恢复默认值执行失败')

        step2 = '======step2:设置ss_txnstatus_cache_size为最大值;expect:设置成功======'
        self.logger.info(step2)
        result1 = Primary_SH.execute_gsguc(
            'set', self.constant.GSGUC_SUCCESS_MSG,
            f'{self.txnstatus_cache_size}={self.txnstatus_cache_size_set}')
        restart_res = Primary_SH.restart_db_cluster()
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.logger.info(status)
        show_ss_txnstatus_cache_size = Primary_SH.execut_db_sql('''show ss_txnstatus_cache_size;''')
        self.logger.info(show_ss_txnstatus_cache_size)
        self.assertEqual("262144", show_ss_txnstatus_cache_size.split("\n")[-2].strip())

        step3 = '======step3:运行tpcc业务;expect:tpcc进程运行======'
        self.logger.info(step3)
        primary_tpcc = ComThread(self.com.start_tpcc,
                                 args=(self.primaryRoot,'/data/benchmarksql-5.0/run',
                                       './runBenchmark.sh primary_write.pg'))
        standby1_tpcc = ComThread(self.com.start_tpcc,
                               args=(self.primaryRoot, '/data/benchmarksql-5.0/run',
                                     './runBenchmark.sh standby_read1.pg'))
        standby2_tpcc = ComThread(self.com.start_tpcc,
                               args=(self.primaryRoot, '/data/benchmarksql-5.0/run',
                                     './runBenchmark.sh standby_read2.pg'))
        primary_tpcc.setDaemon(True)
        standby1_tpcc.setDaemon(True)
        standby2_tpcc.setDaemon(True)
        primary_tpcc.start()
        standby1_tpcc.start()
        standby2_tpcc.start()
        status = Primary_ROOTSH.exec_cmd_under_root("ps -ux | grep './runBenchmark.sh' | grep -v -- '--color'")
        self.assertIn('primary_write.pg', status, '执行失败' + step3)
        status = Primary_ROOTSH.exec_cmd_under_root("ps -ux | grep './runBenchmark.sh' | grep -v -- '--color'")
        self.assertIn('standby_read1.pg', status, '执行失败' + step3)
        status = Primary_ROOTSH.exec_cmd_under_root("ps -ux | grep './runBenchmark.sh' | grep -v -- '--color'")
        self.assertIn('standby_read2.pg', status, '执行失败' + step3)
        time.sleep(5)
        step4 = "======step4:备节点1踢出;expect:踢出成功======"
        self.logger.info(step4)
        result = Primary_SH.exec_cm_ctl(mode='stop', param='-n 2')
        self.logger.info(result)
        self.assertIn('successfully', result, '执行失败' + step4)
        time.sleep(5)
        step5 = "======step5:查询集群状态;expect:集群状态正常======"
        self.logger.info(step5)
        status =  Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.logger.info(status)
        self.assertIn('cluster_state   : Degraded', status, '执行失败' + step5)
        res2 = status.splitlines()[-1].split('|')[1].split('6002')[-1]
        self.assertTrue('S Down    Unknown' in res2 or '     S Unknown Unknown ' in res2,'执行失败' + step5)

        step6 = "======step6:备节点重启加入;expect:reform成功======"
        self.logger.info(step6)
        result = Primary_SH.exec_cm_ctl(mode='start', param='-n 2')
        self.logger.info(result)
        self.assertIn('successfully', result, '执行失败' + step6)
        time.sleep(10)

        time.sleep(20)

        step7 = "======step7:tpcc业务结束,查询集群状态;expect:集群状态正常======"
        self.logger.info(step7)
        status =  Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.logger.info(status)
        self.assertIn('cluster_state   : Normal', status, '执行失败' + step7)
        self.assertIn('P Primary Normal',
                      status.splitlines()[-1].split('|')[0].split('6001')[-1],
                      '执行失败' + step7)
        self.assertIn('S Standby Normal',
                      status.splitlines()[-1].split('|')[1].split('6002')[-1],
                      '执行失败' + step7)

    def tearDown(self):
        step8 = "======step8:环境清理,恢复参数;expect:环境清理成功,恢复参数成功======"
        self.logger.info(step8)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.logger.info(status)
        status = Primary_SH.check_cluster_core_status(status, wait_times=600)
        self.logger.info(status)
        stop_tpcc_cmd = "ps -ef | grep runBenchmark | grep -v grep | " \
                        + "awk '{{print $2}}' | xargs kill -9"
        stop_tpcc = Primary_ROOTSH.exec_cmd_under_root(stop_tpcc_cmd)
        result1 = Primary_SH.execute_gsguc(
            'set', self.constant.GSGUC_SUCCESS_MSG,
            f'{self.txnstatus_cache_size}={self.txnstatus_cache_size_default}')
        restart_res = Primary_SH.restart_db_cluster()
        show_txnstatus_cache_size = self.com.show_param(self.txnstatus_cache_size)

        recovery = Primary_SH.exec_cm_ctl(mode='switchover', param='-a')
        self.logger.info(recovery)
        self.assertIn(self.constant.cm_switchover_success_msg, recovery,
                      '执行失败' + step8)

        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.logger.info(status)

        self.logger.info("-----断言teardown-----")
        self.assertEquals(show_txnstatus_cache_size, '131072', '执行失败' + step8)
        self.assertIn('cluster_state   : Normal', status, '执行失败' + step8)
        self.assertIn('P Primary Normal',
                      status.splitlines()[-1].split('|')[0].split('6001')[-1],
                      '执行失败' + step8)
        self.assertIn('S Standby Normal',
                      status.splitlines()[-1].split('|')[1].split('6002')[-1],
                      '执行失败' + step8)
        self.assertIn('S Standby Normal',
                      status.splitlines()[-1].split('|')[2].split('6003')[-1],
                      '执行失败' + step8)

        self.logger.info(f"-----{os.path.basename(__file__)} end-----")
